﻿using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using OfficeOpenXml;
using OfficeOpenXml.Style;
using Analysis.DAL.Repositories;

namespace Analysis.Code
{
    public class BaseGridPage : BasePage
    {
        public string PageName { get; set; }
        protected string FileName { get; set; }
        protected string CustomColumnPrefix = "Custom ";
        protected bool IsEmptyGrid { get; set; }

        protected DataTable GridData
        {
            get
            {
                if (this.Session[PageName + "_GridData"] != null)
                    return (DataTable)this.Session[PageName + "_GridData"];
                else
                    return null;
            }
            set
            {
                this.Session[PageName + "_GridData"] = value;
            }
        }

        protected DataView GridDataView
        {
            get
            {
                if (GridData != null)
                    return new DataView(GridData, FilterExpression, SortExpression, DataViewRowState.CurrentRows);
                else
                    return null;
            }
        }
        
        protected List<ColumnInfo> ColumnsList
        {
            get
            {
                if (this.Session[PageName + "_ColumnsList"] == null)
                    this.Session[PageName + "_ColumnsList"] = new List<ColumnInfo>();
                return (List<ColumnInfo>)this.Session[PageName + "_ColumnsList"];
            }
            set
            {
                this.Session[PageName + "_ColumnsList"] = value;
            }
        }

        protected List<string> CustomColumnsList
        {
            get
            {
                if (this.Session[PageName + "_CustomColumnsList"] != null)
                    return (List<string>)this.Session[PageName + "_CustomColumnsList"];
                else
                    return null;
            }
            set
            {
                this.Session[PageName + "_CustomColumnsList"] = value;
            }
        }

        protected string SortExpression
        {
            get
            {
                if (this.Session[PageName + "_SortExpression"] != null)
                    return this.Session[PageName + "_SortExpression"].ToString();
                else
                    return "";
            }
            set
            {
                value = "[" + value + "]";
                string result = value + " asc";

                if (!string.IsNullOrEmpty(SortExpression))
                {
                    string[] sortItems = ParseSortExpression();
                    if (sortItems.Length == 2)
                        if (sortItems[0].Equals(value))
                            result = value + " " + (sortItems[1].Equals("asc") ? "desc" : "asc");
                }

                this.Session[PageName + "_SortExpression"] = result;
            }
        }

        protected List<KeyValuePair<string, string>> FilterData
        {
            get
            {
                if (this.Session[PageName + "_FilterData"] == null)
                    this.Session[PageName + "_FilterData"] = new List<KeyValuePair<string, string>>();

                return (List<KeyValuePair<string, string>>)this.Session[PageName + "_FilterData"];
            }
        }

        protected string FilterExpression
        {
            get
            {
                string result = "";
                foreach (KeyValuePair<string, string> f in FilterData)
                {
                    if (!string.IsNullOrEmpty(result))
                        result += " and ";
                    if (IsTextFilter(f.Key))
                        result += string.Format(" ([{0}] like '%{1}%') ", f.Key, f.Value);
                    else 
                        result += string.Format(" ([{0}] = '{1}') ", f.Key, f.Value);
                }
                return result;
            }
        }

        protected bool IsTextFilter(string dataField)
        {
            return (dataField.Equals("ClientId") || dataField.Equals("Address") || dataField.StartsWith(CustomColumnPrefix) || dataField.Equals("TTId") || dataField.Equals("SCUId") || dataField.Equals("GroupingName"));
        }

        protected int PageSize
        {
            get
            {
                if (this.Session[PageName + "_PageSize"] != null)
                    return (int)this.Session[PageName + "_PageSize"];
                else
                    return 20;
            }
            set
            {
                this.Session[PageName + "_PageSize"] = value;
            }
        }

        protected int TotalFilteredItem { get; set; }

        protected void PrepareDataTable()
        {
            DataColumn col = new DataColumn("IsSelected", typeof(bool));
            col.DefaultValue = false;

            GridData.Columns.Add(col);
        }

        public virtual void LoadData()
        {
        }

        public virtual void LoadDataFromDb()
        {
        }

        protected void GenerateCustomColumnList()
        {
            List<string> lstCustom = new List<string>();
            for (int i = 0; i < GridData.Columns.Count; ++i)
            {
                DataColumn col = GridData.Columns[i];
                if (col.ColumnName.Substring(0, Math.Min(CustomColumnPrefix.Length, col.ColumnName.Length)).Equals(CustomColumnPrefix))
                    lstCustom.Add(col.ColumnName.Substring(CustomColumnPrefix.Length));
            }
            CustomColumnsList = lstCustom;
        }

        protected virtual void InitGrid()
        {
            // Создание кастомных колонок в грид
            for (int i = 0; i < CustomColumnsList.Count; ++i)
            {
                TemplateField tmp = new TemplateField();
                tmp.HeaderTemplate = new CustomColumnTemplate(ListItemType.Header, CustomColumnPrefix + CustomColumnsList[i], i);
                tmp.ItemTemplate = new CustomColumnTemplate(ListItemType.Item, CustomColumnPrefix + CustomColumnsList[i], i);
                tmp.FooterTemplate = new CustomColumnTemplate(ListItemType.Footer, CustomColumnPrefix + CustomColumnsList[i], i);
                tmp.EditItemTemplate = new CustomColumnTemplate(ListItemType.EditItem, CustomColumnPrefix + CustomColumnsList[i], i);
                tmp.HeaderText = CustomColumnsList[i];

                //grid.Columns.Insert(7, tmp);
                GetGrid().Columns.Add(tmp);
            }
        }

        protected virtual void grid_RowCreated(Object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.Pager)
            {
                Table pagerTable = (Table)e.Row.Cells[0].Controls[0];

                TableCell cell = new TableCell();
                cell.Text = "Отображать строк: ";
                pagerTable.Rows[0].Cells.AddAt(0, cell);

                cell = new TableCell();
                DropDownList ddl = new DropDownList();
                ddl.Items.Add(new ListItem("20", "20"));
                ddl.Items.Add(new ListItem("30", "30"));
                ddl.Items.Add(new ListItem("50", "50"));
                ddl.Items.Add(new ListItem("100", "100"));
                ddl.Items.Add(new ListItem("200", "200"));
                ddl.Items.Add(new ListItem("300", "300"));

                /*ddl.Items.Add(new ListItem("1", "1"));
                ddl.Items.Add(new ListItem("2", "2"));
                ddl.Items.Add(new ListItem("3", "3"));*/

                ddl.AutoPostBack = true;
                //ddl.CssClass = "form-control";
                ddl.SelectedIndexChanged += new EventHandler(PageCount_SelectedIndexChanged);
                ddl.ID = "ddlPageSize";
                cell.Controls.Add(ddl);
                pagerTable.Rows[0].Cells.AddAt(1, cell);
            }
            else if (e.Row.RowType == DataControlRowType.Header)
            {
                bool isFirst = true;
                GridViewRow row = e.Row;
                for(int i = 0; i < row.Cells.Count; ++i)
                {
                    TableCell cell = row.Cells[i];

                    if (i > 0)
                    {
                        cell.Style.Add("min-width", "170px");
                        cell.Style.Add("white-space", "nowrap");
                    }

                    if (cell.Controls.Count == 0)
                        continue;
                    if (!(cell.Controls[0] is Label))
                        continue;

                    ColumnInfo cInfo = new ColumnInfo();
                    
                    // Считываем название поля
                    string dataField = ((Label)cell.Controls[0]).Text;
                    cInfo.DataField = dataField;
                    cInfo.IsCustom = dataField.StartsWith(CustomColumnPrefix);

                    // Формируем ссылку для сортировки
                    LinkButton lb = new LinkButton();
                    lb.CommandName = "Sort";
                    lb.CommandArgument = dataField;
                    lb.CssClass = "table_header_link";

                    Label lbl = new Label();
                    lbl.Text = GetGrid().Columns[i].HeaderText;
                    
                    cInfo.HeaderText = lbl.Text;
                    cInfo.ColumnWidth = APRepository.GetUserParam(CurrentUserId, string.Format("{0}_grid_{1}_ColumnWidth", PageName, cInfo.HeaderText));
                    string isVisible = APRepository.GetUserParam(CurrentUserId, string.Format("{0}_grid_{1}_ColumnVisible", PageName, cInfo.HeaderText));
                    if (!string.IsNullOrEmpty(isVisible))
                        cInfo.IsVisible = isVisible == "1";
                    if (!string.IsNullOrEmpty(cInfo.ColumnWidth))
                    {
                        //cell.Width = new Unit(cInfo.ColumnWidth);
                        cell.Style["min-width"] = cInfo.ColumnWidth + "px;";
                        cell.Style["max-width"] = cInfo.ColumnWidth + "px;";
                        cell.Style.Add("overflow", "hidden");
                        cell.Style.Add("text-overflow", "ellipsis");
                        cell.Attributes.Add("data-overflow-title", lbl.Text);
                        cell.CssClass += " mightOverflow";
                    }

                    if (isFirst)
                    {
                        ColumnsList.Clear();
                        isFirst = false;
                    }

                    TemplateField tf = GetColumnByHeader(cInfo.HeaderText);
                    if ((tf.Visible) || (cInfo.IsVisible.HasValue))
                        ColumnsList.Add(cInfo);
                    if (cInfo.IsVisible.HasValue)
                        tf.Visible = cInfo.IsVisible.Value;

                    lb.Controls.Add(lbl);
                    Image sortIcon = GetSortIcon(dataField);
                    if (sortIcon != null)
                        lb.Controls.Add(sortIcon);

                    cell.Controls.Add(lb);

                    Literal ltr = new Literal();
                    ltr.Mode = LiteralMode.PassThrough;
                    ltr.Text = "<br/>";
                    cell.Controls.Add(ltr);

                    if (IsTextFilter(dataField))
                    {
                        TextBox tb = new TextBox();
                        tb.ID = "tbFilter" + i.ToString();
                        tb.TextChanged += new EventHandler(Filter_TextChanged);
                        tb.Attributes.Add("data-field", dataField);
                        tb.Style.Add("width", "100%");
                        cell.Controls.Add(tb);
                    }
                    else
                    {
                        // Формируем список для фильтрации
                        DropDownList ddl = new DropDownList();
                        ddl.Items.Add(new ListItem("", dataField));

                        List<ListItem> items = new List<ListItem>();
                        string value;

                        DataView view = GridDataView;
                        DataTable distinctValues = new DataTable();
                        int count = FilterData.Count;
                        if (count > 0 && FilterData.Any(d => d.Key == dataField) && GridData != null)
                        {
                            if (count > 1)
                            {
                                string expression = "";
                                foreach (KeyValuePair<string, string> f in FilterData)
                                {
                                    if (f.Key != dataField)// не учитываем текущий фильтр
                                    {
                                        if (!string.IsNullOrEmpty(expression))
                                            expression += " and ";
                                        if (IsTextFilter(f.Key))
                                            expression += string.Format(" ([{0}] like '%{1}%') ", f.Key, f.Value);
                                        else
                                            expression += string.Format(" ([{0}] = '{1}') ", f.Key, f.Value);
                                    }
                                }
                                distinctValues = new DataView(GridData, expression, SortExpression, DataViewRowState.CurrentRows).ToTable(true, dataField);
                            }
                            else
                            {
                                distinctValues = new DataView(GridData).ToTable(true, dataField);
                            }
                        }
                        else
                        {
                            distinctValues = view.ToTable(true, dataField);
                        }

                        foreach (DataRow dr in distinctValues.Rows)
                        {
                            if (dr.IsNull(dataField))
                                continue;
                            value = dr[dataField].ToString();
                            if (string.IsNullOrEmpty(value))
                                continue;

                            items.Add(new ListItem(value, value));
                        }

                        items.Sort(delegate(ListItem item1, ListItem item2) { return item1.Text.CompareTo(item2.Text); });
                        ddl.Items.AddRange(items.ToArray());
                        ddl.AutoPostBack = true;
                        //ddl.CssClass = "form-control";
                        ddl.SelectedIndexChanged += new EventHandler(Filter_SelectedIndexChanged);
                        ddl.ID = "ddlFilter" + i.ToString();
                        ddl.Style.Add("width", "100%");
                        cell.Controls.Add(ddl);
                    }
                }
                
            }
            
        }

        protected virtual void grid_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.Header)
            {
                GridViewRow row = e.Row;
                for (int i = 0; i < row.Cells.Count; ++i)
                {
                    DropDownList ddl = (DropDownList)e.Row.FindControl("ddlFilter" + i.ToString());
                    if (ddl != null)
                    {
                        string dataField = ddl.Items[0].Value;
                        KeyValuePair<string, string> existsFilter = FilterData.Find(item => item.Key.Equals(dataField));
                        if (!existsFilter.Equals(default(KeyValuePair<string, string>)))
                        {
                            ListItem itm = ddl.Items.FindByText(existsFilter.Value);
                            if (itm != null)
                                itm.Selected = true;
                        }
                    }

                    TextBox tb = (TextBox)e.Row.FindControl("tbFilter" + i.ToString());
                    if (tb != null)
                    {
                        string dataField = tb.Attributes["data-field"];
                        KeyValuePair<string, string> existsFilter = FilterData.Find(item => item.Key.Equals(dataField));
                        if (!existsFilter.Equals(default(KeyValuePair<string, string>)))
                        {
                            tb.Text = existsFilter.Value;
                        }
                    }
                }

                CheckBox chk = (CheckBox)e.Row.FindControl("chbSelectAll");
                if (chk != null)
                {
                    chk.Checked = true;
                }
            }
            else if (e.Row.RowType == DataControlRowType.Pager)
            {
                DropDownList ddl = (DropDownList)e.Row.FindControl("ddlPageSize");
                if (ddl != null)
                    ddl.SelectedValue = PageSize.ToString();
            }
            else if (e.Row.RowType == DataControlRowType.DataRow)
            {
                CheckBox chkAll = (CheckBox)GetGrid().HeaderRow.FindControl("chbSelectAll");
                CheckBox chkItem = (CheckBox)e.Row.FindControl("chbIsSelected");
                if ((chkAll != null) && (chkItem != null))
                {
                    chkAll.Checked = chkAll.Checked && chkItem.Checked;
                }
                
            }
        }

        protected virtual void grid_PreRender(object sender, EventArgs e)
        {
            //делаем пейджер видимым
            GridView grid = (GridView)sender;
            Table pagerTable;
            if (grid != null)
            {
                GridViewRow pagerRow = (GridViewRow)grid.BottomPagerRow;
                if (pagerRow != null)
                {
                    pagerRow.Visible = true;
                    //добавляем строки для пейджера
                    pagerTable = (Table)pagerRow.Cells[0].Controls[0];
                    TableCell cell = new TableCell();
                    cell.Text = String.Format("<div><span class='count-page' style='position: relative;'>Согласно фильтрам: {0} &nbsp&nbsp Всего записей: {1}</span></div>", GridDataView.Count, GridData.Rows.Count);
                    pagerTable.Rows[0].Cells.Add(cell);
                }
                pagerRow = (GridViewRow)grid.TopPagerRow;
                if (pagerRow != null)
                {
                    pagerRow.Visible = true;
                    TableCell cell = new TableCell();
                    cell.Text = String.Format("<div><span class='count-page' style='position: relative;'>Согласно фильтрам: {0} &nbsp&nbsp Всего записей: {1}</span></div>", GridDataView.Count, GridData.Rows.Count);
                    pagerTable = (Table)pagerRow.Cells[0].Controls[0];
                    pagerTable.Rows[0].Cells.Add(cell);
                }
            }
            
        }

        protected void grid_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            (sender as GridView).PageIndex = e.NewPageIndex;
            LoadData();
        }

        protected void grid_Sorting(object sender, GridViewSortEventArgs e)
        {
            SortExpression = e.SortExpression;
            LoadData();
        }

        public void RemoveCustomColumn(string columnHeader)
        {
            GridView grid = GetGrid();
            int index = CustomColumnsList.IndexOf(columnHeader);
            int i = GetColumnIndexByHeader(columnHeader);
            TemplateField tmp = (TemplateField)grid.Columns[i];
            tmp.HeaderTemplate = new CustomColumnTemplate(ListItemType.Header, "_Custom " + columnHeader, index);
            tmp.ItemTemplate = new CustomColumnTemplate(ListItemType.Item, "_Custom " + columnHeader, index);
            tmp.FooterTemplate = new CustomColumnTemplate(ListItemType.Footer, "_Custom " + columnHeader, index);
            tmp.EditItemTemplate = new CustomColumnTemplate(ListItemType.EditItem, "_Custom " + columnHeader, index);
            tmp.HeaderText = columnHeader;
            grid.Columns[i].Visible = false;

            LoadDataFromDb();
            LoadData();
        }

        public void AddCustomColumn()
        {
            LoadDataFromDb();

            GridView grid = GetGrid();
            int index = CustomColumnsList.Count - 1;
            TemplateField tmp = new TemplateField();
            tmp.HeaderTemplate = new CustomColumnTemplate(ListItemType.Header, "Custom " + CustomColumnsList[index], index);
            tmp.ItemTemplate = new CustomColumnTemplate(ListItemType.Item, "Custom " + CustomColumnsList[index], index);
            tmp.FooterTemplate = new CustomColumnTemplate(ListItemType.Footer, "Custom " + CustomColumnsList[index], index);
            tmp.EditItemTemplate = new CustomColumnTemplate(ListItemType.EditItem, "Custom " + CustomColumnsList[index], index);
            tmp.HeaderText = CustomColumnsList[index];
            grid.Columns.Add(tmp);

            LoadData();
        }

        public void EditCustomColumn(string oldName, string newName)
        {
            int index = CustomColumnsList.IndexOf(oldName);
            int i = GetColumnIndexByHeader(oldName);
            GridView grid = GetGrid();
            TemplateField tmp = (TemplateField)grid.Columns[i];
            tmp.HeaderTemplate = new CustomColumnTemplate(ListItemType.Header, "Custom " + newName, index);
            tmp.ItemTemplate = new CustomColumnTemplate(ListItemType.Item, "Custom " + newName, index);
            tmp.FooterTemplate = new CustomColumnTemplate(ListItemType.Footer, "Custom " + newName, index);
            tmp.EditItemTemplate = new CustomColumnTemplate(ListItemType.EditItem, "Custom " + newName, index);
            tmp.HeaderText = newName;
        }

        /*protected void grid_RowEditing(object sender, GridViewEditEventArgs e)
        {
            (sender as GridView).EditIndex = e.NewEditIndex;
            LoadData();
        }

        protected void grid_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
        {
            (sender as GridView).EditIndex = -1;
            LoadData();
        }*/

        protected void SelectAll_CheckedChange(object sender, EventArgs e)
        {
            bool isChecked = (sender as CheckBox).Checked;
            GridView grid = GetGrid();
            foreach (DataKey key in grid.DataKeys)
            {
                DataRow[] drs = GridData.Select(grid.DataKeyNames[0] + " = " + key.Value.ToString());
                if (drs.Length > 0)
                    drs[0]["IsSelected"] = isChecked;
            }
            LoadData();
        }

        protected void selected_CheckedChange(object sender, EventArgs e)
        {
            CheckBox chk = (CheckBox)sender;
            GridViewRow gr = (GridViewRow)chk.Parent.Parent;
            GridView grid = GetGrid();
            string id = grid.DataKeys[gr.RowIndex].Value.ToString();
            DataRow[] drs = GridData.Select(grid.DataKeyNames[0] + " = " + id);
            if (drs.Length > 0)
                drs[0]["IsSelected"] = chk.Checked;
        }

        protected void PageCount_SelectedIndexChanged(Object sender, EventArgs e)
        {
            DropDownList ddl = sender as DropDownList;
            GetGrid().PageSize = PageSize = Convert.ToInt32(ddl.SelectedValue);
                       
            LoadData();
        }

        protected void Filter_SelectedIndexChanged(Object sender, EventArgs e)
        {
            string postbackControl = Page.Request.Params.Get("__EVENTTARGET");
            DropDownList ddl = sender as DropDownList;
            if (!postbackControl.Contains(ddl.ID))
                return;

            string dataField = ddl.Items[0].Value;
            string selectedText = ddl.Items[ddl.SelectedIndex].Text;

            KeyValuePair<string, string> existsFilter = FilterData.Find(i => i.Key.Equals(dataField));
            if (!existsFilter.Equals(default(KeyValuePair<string, string>)))
                FilterData.Remove(existsFilter);

            if (ddl.SelectedIndex > 0)
                FilterData.Add(new KeyValuePair<string, string>(dataField, selectedText));

            LoadData();
        }

        protected void Filter_TextChanged(Object sender, EventArgs e)
        {
            TextBox tb = sender as TextBox;

            string dataField = tb.Attributes["data-field"];
            string selectedText = tb.Text;

            KeyValuePair<string, string> existsFilter = FilterData.Find(i => i.Key.Equals(dataField));
            if (!existsFilter.Equals(default(KeyValuePair<string, string>)))
                FilterData.Remove(existsFilter);

            if (!string.IsNullOrEmpty(selectedText))
                FilterData.Add(new KeyValuePair<string, string>(dataField, selectedText));

            LoadData();
        }

        protected void btnExcelExport_Click(object sender, EventArgs e)
        {
            ExcelPackage pck = new ExcelPackage();
            var ws = pck.Workbook.Worksheets.Add(PageName);

            int top = 1;
            int rowStartAutofit = 1;
            int left = 0;
            
            // Выводим заголовки колонок и запоминаем названия полей бд (в таком же порядке)
            for (int i = 0; i < ColumnsList.Count; ++i)
            {
                ++left;
                ws.Cells[top, left].Value = ColumnsList[i].HeaderText;
            }

            // Стиль заголовка
            var range = ws.Cells[top, 1, top, left];
            range.Style.Font.Bold = true;
            var border = range.Style.Border;
            border.Bottom.Style = border.Top.Style = border.Left.Style = border.Right.Style = ExcelBorderStyle.Thin;
            range.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;

            ++top;
            left = 1;

            // Выводим данные
            DataView dv = new DataView(GridData, FilterExpression, SortExpression, DataViewRowState.CurrentRows);
            for (int i = 0; i < dv.Count; ++i)
            {
                for (int j = 0; j < ColumnsList.Count; ++j)
                {
                    if (dv[i][ColumnsList[j].DataField] != System.DBNull.Value)
                        ws.Cells[top + i, left + j].Value = dv[i][ColumnsList[j].DataField];
                }
            }

            range = ws.Cells[top, left, top + dv.Count - 1, left + ColumnsList.Count - 1];
            border = range.Style.Border;
            border.Bottom.Style = border.Top.Style = border.Left.Style = border.Right.Style = ExcelBorderStyle.Thin;

            top += dv.Count - 1;
            ws.Cells[rowStartAutofit, left, top, left + ColumnsList.Count - 1].AutoFitColumns();

            Response.Clear();
            Response.AddHeader("content-disposition", "attachment;  filename=" + FileName);
            Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
            Response.BinaryWrite(pck.GetAsByteArray());
            Response.End();
        }
        
        public virtual void ExcelImport(FileUpload fu)
        {
        }

        public virtual GridView GetGrid()
        {
            return null;
        }

        protected virtual UpdatePanel GetUP()
        {
            return null;
        }

        protected TemplateField GetColumnByHeader(string headerText)
        {
            GridView grid = GetGrid();
            foreach (TemplateField i in grid.Columns)
                if (i.HeaderText.Equals(headerText))
                    return i;

            return null;
        }

        protected int GetColumnIndexByHeader(string headerText)
        {
            GridView grid = GetGrid();
            for (int i = 0; i < grid.Columns.Count; ++i)
                if (grid.Columns[i].HeaderText.Equals(headerText))
                    return i;

            return -1;
        }

        protected string[] ParseSortExpression()
        {
            string colName = "";
            string dirName = "";

            if (!string.IsNullOrEmpty(SortExpression))
            {
                int index = SortExpression.LastIndexOf(" ");
                colName = SortExpression.Substring(0, index);
                dirName = SortExpression.Substring(index + 1);
            }

            return new string[] { colName, dirName };

        }

        protected Image GetSortIcon(string dataField)
        {
            Image result = null;
            dataField = "[" + dataField + "]";
            if (!string.IsNullOrEmpty(SortExpression))
            {
                string[] sortItems = ParseSortExpression();
                if (sortItems.Length == 2)
                    if (sortItems[0].Equals(dataField))
                    {
                        result = new Image();
                        result.CssClass = "sort_icon";
                        if (sortItems[1].Equals("asc"))
                            result.ImageUrl = "~/Images/sort_up.png";
                        else
                            result.ImageUrl = "~/Images/sort_down.png";
                    }
            }

            return result;
        }

    }

    public class CustomColumnTemplate : ITemplate
    {
        protected string CustomColumnPrefix = "Custom ";
        private ListItemType _templateType;
        private string _columnName;
        private int _columnIndex;
        public string ColumnHeader
        {
            get
            {
                if (_columnName.Substring(0, CustomColumnPrefix.Length).Equals(CustomColumnPrefix))
                    return _columnName.Substring(CustomColumnPrefix.Length);
                else
                    return _columnName;
            }
        }
        private string GetDataValue(object dataItem)
        {
            object dataValue = DataBinder.Eval(dataItem, _columnName);
            if (dataValue != DBNull.Value)
                return dataValue.ToString();
            else
                return "";
        }

        public CustomColumnTemplate(ListItemType type, string colname, int columnIndex)
        {
            _templateType = type;
            _columnName = colname;
            _columnIndex = columnIndex;
        }

        void ITemplate.InstantiateIn(System.Web.UI.Control container)
        {
            Label lbl;
            TextBox tb;

            switch (_templateType)
            {
                case ListItemType.Header:
                    lbl = new Label();
                    lbl.Visible = false;
                    lbl.Text = _columnName;
                    container.Controls.Add(lbl);

                    /*lbl = new Label();
                    lbl.Text = ColumnHeader;
                    container.Controls.Add(lbl);*/
                    break;

                case ListItemType.Item:
                    tb = new TextBox(); 
                    tb.DataBinding += new EventHandler(control_DataBinding);
                    tb.CssClass = "form-control";
                    tb.ValidationGroup = "updateItem";
                    tb.Attributes.Add("placeholder", "Введите " + ColumnHeader.ToLower());
                    tb.ID = "txtCustom" + _columnIndex.ToString();
                    container.Controls.Add(tb);
                    break;
            }
        }
        
        protected void control_DataBinding(object sender, EventArgs e)
        {
            GridViewRow container;
            if (sender is Label)
            {
                Label lbl = (sender as Label);
                container = (GridViewRow)lbl.NamingContainer;
                lbl.Text = GetDataValue(container.DataItem);
            }
            else if (sender is TextBox)
            {
                TextBox tb = (sender as TextBox);
                container = (GridViewRow)tb.NamingContainer;
                tb.Text = GetDataValue(container.DataItem);
            }
        }
    }

    public class ColumnInfo
    {
        public string DataField { get; set; }
        public string HeaderText { get; set; }
        public string ColumnWidth { get; set; }
        public bool IsCustom { get; set; }
        public bool? IsVisible { get; set; }
        public bool IsVisibleBinding 
        { 
            get 
            {
                return IsVisible.HasValue ? IsVisible.Value : true;
            }
        }
    }
}